package com.lonely.api.mes.util;

import cn.hutool.core.lang.Assert;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.http.*;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * @author : 黄志标
 * @date: 2025/11/12 14:12
 * @description:
 */
public class RestTemplateUtil {


    private static final RestTemplate restTemplate;

    static {
        // 配置连接池和超时
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        connectionManager.setMaxTotal(100);
        connectionManager.setDefaultMaxPerRoute(20);

        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(5000)    // 连接超时 5s
                .setSocketTimeout(10000)  // 读取超时 10s
                .build();

        CloseableHttpClient httpClient = HttpClients.custom()
                .setConnectionManager(connectionManager)
                .setDefaultRequestConfig(requestConfig)
                .build();

        HttpComponentsClientHttpRequestFactory factory =
                new HttpComponentsClientHttpRequestFactory(httpClient);

        restTemplate = new RestTemplate(factory);
        // 设置默认字符集为 UTF-8（避免中文乱码）
        restTemplate.getMessageConverters().forEach(converter -> {
            if (converter instanceof org.springframework.http.converter.StringHttpMessageConverter) {
                ((org.springframework.http.converter.StringHttpMessageConverter) converter)
                        .setDefaultCharset(StandardCharsets.UTF_8);
            }
        });
    }

    // ------------------ GET 请求 ------------------

    /**
     * GET 请求，返回字符串
     */
    public static String getForString(String url) {
        return getForString(url, null);
    }

    /**
     * GET 请求（带 Headers），返回字符串
     */
    public static String getForString(String url, Map<String, String> headers) {
        Assert.notBlank(url, "URL 不能为空");
        HttpEntity<?> entity = buildHttpEntity(null, headers);
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
        handleResponse(response);
        return response.getBody();
    }

    /**
     * GET 请求，返回指定类型对象（自动 JSON 反序列化）
     */
    public static <T> T getForObject(String url, Class<T> responseType) {
        return getForObject(url, responseType, null);
    }

    /**
     * GET 请求（带 Headers），返回对象
     */
    public static <T> T getForObject(String url, Class<T> responseType, Map<String, String> headers) {
        Assert.notBlank(url, "URL 不能为空");
        HttpEntity<?> entity = buildHttpEntity(null, headers);
        ResponseEntity<T> response = restTemplate.exchange(url, HttpMethod.GET, entity, responseType);
        handleResponse(response);
        return response.getBody();
    }

    // ------------------ POST 请求 ------------------

    /**
     * POST JSON 请求，返回字符串
     */
    public static String postForString(String url, Object requestBody) {
        return postForString(url, requestBody, null);
    }

    /**
     * POST JSON 请求（带 Headers），返回字符串
     */
    public static String postForString(String url, Object requestBody, Map<String, String> headers) {
        Assert.notBlank(url, "URL 不能为空");
        HttpEntity<Object> entity = buildHttpEntity(requestBody, headers);
        ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);
        handleResponse(response);
        return response.getBody();
    }

    /**
     * POST JSON 请求，返回指定类型对象
     */
    public static <T> T postForObject(String url, Object requestBody, Class<T> responseType) {
        return postForObject(url, requestBody, responseType, null);
    }

    /**
     * POST JSON 请求（带 Headers），返回对象
     */
    public static <T> T postForObject(String url, Object requestBody, Class<T> responseType, Map<String, String> headers) {
        Assert.notBlank(url, "URL 不能为空");
        HttpEntity<Object> entity = buildHttpEntity(requestBody, headers);
        ResponseEntity<T> response = restTemplate.postForEntity(url, entity, responseType);
        handleResponse(response);
        return response.getBody();
    }

    // ------------------ 内部工具方法 ------------------

    private static HttpEntity<Object> buildHttpEntity(Object body, Map<String, String> headers) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        httpHeaders.setAccept(java.util.Collections.singletonList(MediaType.APPLICATION_JSON));

        if (headers != null && !headers.isEmpty()) {
            headers.forEach(httpHeaders::set);
        }

        return new HttpEntity<>(body, httpHeaders);
    }

    /**
     * 统一处理响应状态码（非 2xx 抛异常）
     */
    private static <T> void handleResponse(ResponseEntity<T> response) {
        if (!response.getStatusCode().is2xxSuccessful()) {
            throw new RestClientException("HTTP 请求失败，状态码: " + response.getStatusCode() +
                    ", 响应体: " + (response.getBody() != null ? response.getBody().toString() : "null"));
        }
    }

    // ------------------ 获取原始 RestTemplate（高级用法） ------------------

    public static RestTemplate getRestTemplate() {
        return restTemplate;
    }
}
